/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package view;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.logging.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

/**
 * Cette classe définit une brique de type Graphe qui hérite la classe View
 * et qui implémente l'interface ActionListener.
 * @author NGUYEN Dac Cong Tai
 */
public class GrapheView extends View implements ActionListener{
    private DrawingPane drawing;
    private JPanel main ;
    private ArrayList listNomsComposantes;

    /**
     * Constructeur d'une brique de type Graphe en appelant le constructeur de la classe mère.
     * @param brique l'élément contient des informations de la brique
     * @param ecran la dimension de l'écran actuel
     * @param element l'élément contient les textes pour cette brique
     * @param langue le code de la langue d'affichage
     * @param typeProfil le texte indique le type du profil (profil d'élèves ou profil de groupe)
     * @throws UnsupportedEncodingException
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    public GrapheView(Element brique, Dimension ecran, Element element, String langue, String typeProfil) throws UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException {
        super(brique, ecran, element, langue, typeProfil);

        String nom = brique.getAttribute("nom");

        Element rootEl = perl.Utility.getElement(perl.Utility.getPath(this, "/Fichiers systeme/Parametres/modele.xml"));
        //String hexa = View.getHexaColor(rootEl.getElementsByTagName("type"),"2");
        Color color = View.decodeColor(rootEl.getElementsByTagName("type"),"2");
        setBorder(new LineBorder(color, View.thickness));
        setPreferredSize(new Dimension((ecran.width-50)/3, (ecran.height-155)/2));
        setToolTipText(((Element)element.getElementsByTagName("Brique").item(0)).getElementsByTagName(langue).item(0).getTextContent()+" "+nom);
        setLayout(new BorderLayout());

        JTextArea name = new JTextArea(nom);
        name.setForeground(View.getTextColor(color));
        name.setLineWrap(true);
        name.setEditable(false);
        name.setBackground(color);
        name.setFont(View.getTitle());

        String[] operation={((Element)element.getElementsByTagName("Moyenne").item(0)).getElementsByTagName(langue).item(0).getTextContent(),((Element)element.getElementsByTagName("Somme").item(0)).getElementsByTagName(langue).item(0).getTextContent()};

        JPanel comboPanel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.weightx=0.0;

        c.gridy = 0;
        c.gridx = 0;
        NodeList listEchelles = brique.getElementsByTagName("echelle");
        typeOperations = new ArrayList<Boolean>();
        listComboBox = new ArrayList<JComboBox>();
        listMenuVal = new ArrayList<JMenu>();
        for (int i=0; i<listEchelles.getLength(); i++){
            JLabel label = new JLabel(((Element)element.getElementsByTagName("Valeur").item(0)).getElementsByTagName(langue).item(0).getTextContent()+" "+(i+1)+":");
            c.insets= new Insets(0, 0, 0, 0);
            comboPanel.add(label,c);
            c.gridx++;
            JComboBox comboBox = new JComboBox(operation);
            listComboBox.add(comboBox);
            comboBox.setName(String.valueOf(i));
            comboBox.addActionListener(this);
            typeOperations.add(false);
            if(c.gridx==5){
                c.insets= new Insets(0, 0, 0, 0);
                comboPanel.add(comboBox,c);
                c.gridx =0;
                c.gridy++;
            } else {
                c.insets= new Insets(0, 0, 0, 10);
                comboPanel.add(comboBox,c);
                c.gridx ++;
            }
        }

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(name, BorderLayout.NORTH);
        if(c.gridy>1){
            JScrollPane comboScroll = new JScrollPane(comboPanel);
            comboScroll.setBorder(null);
            comboScroll.setPreferredSize(new Dimension(GroupLayout.DEFAULT_SIZE, 40));
            panel.add(comboScroll, BorderLayout.CENTER);
        }else
            panel.add(comboPanel, BorderLayout.CENTER);
        add(panel,BorderLayout.NORTH);

        main = new JPanel();
        listNomsComposantes = new ArrayList();

        main.setLayout(new BorderLayout());
        main.setBackground(Color.white);
        main.add(createTree(brique, element, langue, typeOperations),BorderLayout.NORTH);

        drawing = new DrawingPane(brique.getElementsByTagName("liens"),listNomsComposantes, ecran);
        main.add(drawing,BorderLayout.CENTER);

        scrollPane = new JScrollPane(main);
        scrollPane.setBorder(null);
        add(scrollPane, BorderLayout.CENTER);
    }


    /**
     * Traite des éléments qui sont des liens.
     * @param node le noeud contient des informations du lien
     * @param vues l'élément contient les textes pour ce lien
     * @param langue le code de la langue d'affichage
     * @param typeOperation une liste des booléens définit les types d'opération des valeurs (false = moyenne / true = somme)
     * @return un arbre d'exploitation de type DefaultMutableTreeNode contient des informations de ce lien
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    private DefaultMutableTreeNode traiterLien(Node node, Element vues, String langue, ArrayList<Boolean> typeOperation) throws ParserConfigurationException, SAXException, IOException{
        Element lien = (Element) node;
        String de = lien.getAttribute("de").toString();
        String vers = lien.getAttribute("vers").toString();
        String commentaire = lien.getAttribute("commentaire").toString();

        DefaultMutableTreeNode nodeLien = new DefaultMutableTreeNode(de+" ("+(listNomsComposantes.indexOf(de)+1)+")  ---> "+vers+" ("+(listNomsComposantes.indexOf(vers)+1)+")");
        if(!commentaire.equals("") && !commentaire.equals(" ")){
            DefaultMutableTreeNode nodeCommentaire = new DefaultMutableTreeNode(((Element)vues.getElementsByTagName("Commentaires").item(0)).getElementsByTagName(langue).item(0).getTextContent()+": "+commentaire);
            
            nodeLien.add(nodeCommentaire);
        }

        Node sousComposante = node.getFirstChild();
        int indexVal=0;
        int index=0;
        while(index<node.getChildNodes().getLength()){
        //System.out.println("--<<<"+sousComposant.getNodeName());
            if (sousComposante.getNodeName().equals("commentaires")){
                View.getCommentaire((Element) sousComposante, nodeLien, vues, langue);
            }else if (sousComposante.getNodeName().equals("valeur")){
                String type = ((Element)sousComposante).getAttribute("id_echelle");
                super.getEvaluation((Element) sousComposante, type, nodeLien, typeOperation, indexVal, typeProfil);
                indexVal++;
            }
            sousComposante = sousComposante.getNextSibling();
            index++;
        }
        return nodeLien;
    }

    /**
     * Traite des éléments qui sont des composantes.
     * @param composante l'élément contient des informations du composante
     * @param vues l'élément contient les textes pour ce composante
     * @param langue le code de la langue d'affichage
     * @param typeOperation une liste des booléens définit les types d'opération des valeurs (false = moyenne / true = somme)
     * @return un arbre d'exploitation de type DefaultMutableTreeNode contient des informations de ce composante
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    public DefaultMutableTreeNode traiterComposante(Element composante, Element vues, String langue, ArrayList<Boolean> typeOperation) throws ParserConfigurationException, SAXException, IOException {
        //String nomComposante = composante.getAttributes().getNamedItem("nom").toString().replace("nom", "composante").replace("=", " ");
        String nomComposante = composante.getAttribute("nom");
        if(!listNomsComposantes.contains(nomComposante))
            listNomsComposantes.add(nomComposante);

        DefaultMutableTreeNode nodeComposante = new DefaultMutableTreeNode(((Element)vues.getElementsByTagName("Composante").item(0)).getElementsByTagName(langue).item(0).getTextContent()+" "+(listNomsComposantes.indexOf(nomComposante)+1)+" \""+nomComposante+" \"");

        Node sousComposante = composante.getFirstChild();
        int indexVal=0;
        int index=0;
        while(index<composante.getChildNodes().getLength()){
        //System.out.println("--<<<"+sousComposant.getNodeName());
            if (sousComposante.getNodeName().equals("commentaires")){
                View.getCommentaire((Element) sousComposante, nodeComposante, vues, langue);
            }else if (sousComposante.getNodeName().equals("valeur")){
                String type = ((Element)sousComposante).getAttribute("id_echelle");
                super.getEvaluation((Element) sousComposante, type, nodeComposante, typeOperation, indexVal, typeProfil);
                indexVal++;
            } 
            sousComposante = sousComposante.getNextSibling();
            index++;
        }
        return nodeComposante;
    }

    /**
     * Crée un arbre d'exploitation d'une brique.
     * @param brique l'élément contient des informations de la brique
     * @param vues l'élément contient les textes pour ce composante
     * @param langue le code de la langue d'affichage
     * @param typeOperation une liste des booléens définit les types d'opération des valeurs (false = moyenne / true = somme)
     * @return un arbre d'exploitation de type JTree contient des informations de cette brique
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    public JTree createTree(Element brique, Element vues, String langue, ArrayList<Boolean> typeOperation) throws ParserConfigurationException, SAXException, IOException{
        Node element = brique.getFirstChild();
        DefaultMutableTreeNode tree = new DefaultMutableTreeNode(brique.getAttribute("nom"),true);
        int index=0;
        while(index<brique.getChildNodes().getLength()){
            if (element.getNodeName().equals("commentaires")){
                View.getCommentaire((Element) element, tree, vues, langue);
            }else if (element.getNodeName().equals("arbre_des_composantes")){
                NodeList listArbreDesComposantes = brique.getElementsByTagName("arbre_des_composantes");

                for (int i=0; i<listArbreDesComposantes.getLength();i++){
                    //Recuperer l'arbre des composantes
                    Element arbreComposante = (Element) listArbreDesComposantes.item(i);

                    // Recuperer la liste des composantes
                    NodeList listComposantes = arbreComposante.getElementsByTagName("composante");

                    for (int j=0; j<listComposantes.getLength(); j++){

                        //Element composant = (Element) listComposant.item(j);
                        Node composant = listComposantes.item(j);

                        DefaultMutableTreeNode tmp = traiterComposante((Element)composant, vues, langue, typeOperation);

                        tree.add(tmp);
                    }
                }
            } else if (element.getNodeName().equals("liens")){
                NodeList listArbreLiens = brique.getElementsByTagName("liens");
                for(int m=0; m<listArbreLiens.getLength(); m++){
                    Element arbreLiens = (Element) listArbreLiens.item(m);
                    DefaultMutableTreeNode liens = new DefaultMutableTreeNode(((Element)vues.getElementsByTagName("Liens").item(0)).getElementsByTagName(langue).item(0).getTextContent());
                    NodeList listLiens = arbreLiens.getElementsByTagName("lien");
                    for (int n=0; n<listLiens.getLength(); n++){
                        Node lien = listLiens.item(n);
                        DefaultMutableTreeNode tmp = traiterLien(lien, vues, langue, typeOperation);

                        liens.add(tmp);
                    }
                    tree.add(liens);
                }
            }
            element = element.getNextSibling();
            index++;
        }

        return super.convertToJTree(tree);
    }

    /**
     * Définit les actions.
     * @param e l'action
     */
    public void actionPerformed(ActionEvent e) {
        /*JComboBox cb = (JComboBox)e.getSource();
        String itemSelected = (String)cb.getSelectedItem();
        int indexCB = Integer.parseInt(cb.getName());*/

        String action = e.getActionCommand();
        JMenuItem menu = null;
        int indexItemSelected=0;
        int indexCB=0;
        if(e.getSource().getClass().equals(JComboBox.class)){
            JComboBox cb = (JComboBox)e.getSource();
            indexItemSelected = cb.getSelectedIndex();
            indexCB = Integer.parseInt(cb.getName());
        } else if(e.getSource().getClass().equals(JMenuItem.class)){
            String[] split = action.split(",");
            indexCB = Integer.parseInt(split[0]);
            indexItemSelected = Integer.parseInt(split[1]);
            menu = (JMenuItem) e.getSource();
        }
        try {
            if (indexItemSelected==0) {
                listComboBox.get(indexCB).setSelectedIndex(0);
                typeOperations.set(indexCB, false);
                main.removeAll();
                main.add(createTree(brique, parametre, codeLangue, typeOperations),BorderLayout.NORTH);
                main.add(drawing,BorderLayout.CENTER);
                scrollPane.getViewport().add(main);
                if(menu!=null){
                    ((JMenuItem)((JPopupMenu)menu.getParent()).getSubElements()[0]).setEnabled(false);
                    ((JMenuItem)((JPopupMenu)menu.getParent()).getSubElements()[1]).setEnabled(true);
                } else {
                    listMenuVal.get(indexCB).getItem(0).setEnabled(false);
                    listMenuVal.get(indexCB).getItem(1).setEnabled(true);
                }
            } else if (indexItemSelected==1) {
                listComboBox.get(indexCB).setSelectedIndex(1);
                typeOperations.set(indexCB, true);
                main.removeAll();
                main.add(createTree(brique, parametre, codeLangue, typeOperations),BorderLayout.NORTH);
                main.add(drawing,BorderLayout.CENTER);
                scrollPane.getViewport().add(main);
                if(menu!=null){
                    ((JMenuItem)((JPopupMenu)menu.getParent()).getSubElements()[1]).setEnabled(false);
                    ((JMenuItem)((JPopupMenu)menu.getParent()).getSubElements()[0]).setEnabled(true);
                }else {
                    listMenuVal.get(indexCB).getItem(1).setEnabled(false);
                    listMenuVal.get(indexCB).getItem(0).setEnabled(true);
                }
            }
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(ListeView.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(ListeView.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ListeView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}
